﻿package 
{
	import exampleSupport.MarkerOutliner;
	
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import org.libspark.flartoolkit.core.FLARCode;
	import org.libspark.flartoolkit.core.param.FLARParam;
	import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
	import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
	import org.libspark.flartoolkit.core.types.FLARDoublePoint2d;
	import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
	import org.libspark.flartoolkit.pv3d.FLARBaseNode;
	
	
	public class Main extends Sprite 
	{
		/*
		 * camera_para.dat is a Binary file created by --PROGRAM NAME HERE--
		 * Basically what it does is give information for FlarToolkit to
		 * correct distortion and stuff like that, that your camera does.
		 * It will also contain a Projection Matrix
		 */
		[Embed(source="../lib/camera_para.dat", mimeType="application/octet-stream")]
		private var CameraParameters:Class;
		
		/*
		 * mikko.pat is a Pattern I've created using the Air App provided by
		 * Saqoosha. There are 4 16x48 matrices. One 16x48 matrix represents
		 * the colours in your marker from one direction. Basically your marker
		 * is reduced to 16 pixels by Saqoosha's air app. So it is
		 * 16 by (16 x 3 colours red, green, blue)= 16 by 48 matrix
		 */
		[Embed(source="../lib/square.pat", mimeType="application/octet-stream")]
		private var MarkerPattern:Class;
		
		private var cameraParameters:FLARParam;
		private var markerPattern:FLARCode;
		private var raster:FLARRgbRaster_BitmapData;
		private var detector:FLARSingleMarkerDetector;
		
		private var cam:Camera;
		private var vid:Video;
		private var capture:BitmapData;
		
		private var mainContainer:FLARBaseNode;

		
		private var trans:FLARTransMatResult;
		private var prevSet:Boolean = false;
		private var prevZ:Number = 0;
		
		private var markerOutliner:MarkerOutliner;
		private static const RECTANGLE_WIDTH:Number = 100;
		private static const RECTANGLE_HEIGHT:Number = 100;

		public var ballX:Number = 0;
		public var ballY:Number = 0;
		public var velX:Number = 10;
		public var velY:Number = 6;
		private static const BALL_RADIUS:Number = 15;
		public var x_boundarie:Number = 640 / 4;
		public var y_boundarie:Number = 480 / 3;
		
		public var Background:Loader;
		public var Back_URL:URLRequest;
		
		public var Ball_Img:Loader;
		public var Ball_URL:URLRequest;
		
		public var Player_Img:Loader;
		public var Player_URL:URLRequest;
		


		
		public function Main():void 
		{
			/* Cargamos el Fondo... La Canchita papa */
			Background = new Loader();
			Back_URL = new URLRequest("../art/Field.swf");
			Background.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
			Background.load(Back_URL);
			
			/* Cargamos el Balon*/
			Ball_Img = new Loader();
			Ball_URL = new URLRequest("../art/Pelota.swf");
			//Ball_Img.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
			//Ball_Img.load(Ball_URL);
			
			/* Como diria el Coco, los Players...*/
			Player_Img = new Loader();
			Player_URL = new URLRequest("../art/Player1.swf");
			
			
			
			/*
			 * cameraParameters will hold our parameters from the camera noted above.
			 * Flar will use the camera parameters to make your 3d stuff
			 * look right
			 */
			cameraParameters = new FLARParam();
			cameraParameters.loadARParam(new CameraParameters() as ByteArray);
			
			/*
			 * markerPattern will hold the data from our pattern file for Flar
			 * to use to look for our Marker
			 */
			markerPattern = new FLARCode(16, 16);
			markerPattern.loadARPatt(new MarkerPattern());
			
			//Get our webcam going
			cam = Camera.getCamera();
			//Set the webcam to run as 640x480
			//at 30 frames per second
			cam.setMode(640, 480, 40);
			
			//Create a new video object to show our webcam
			vid = new Video();
			vid.width = 640;
			vid.height = 480;
			vid.x = 0;
			vid.y = 0;
			vid.attachCamera(cam);
			vid.visible = true;
			addChild(vid);
			
			/*
			 * capture will hold BitmapData of what is shown on the 
			 * webcam FlarToolkit will use this bitmapdata to look
			 * for our mark pattern
			 * 
			 * we will need to redraw vid to capture every frame
			 */
			capture = new BitmapData(vid.width, vid.height, true, 0x0);
			capture.draw(vid);
			
			/*
			 * raster will hold our BitmapData for Flar to use
			 */
			raster = new FLARRgbRaster_BitmapData(capture);
			detector = new FLARSingleMarkerDetector(cameraParameters, markerPattern, 80);
			
			// MarkerOutliner is a simple class that draws an outline
			// around the edge of detected markers.
			this.markerOutliner = new MarkerOutliner();
			this.markerOutliner.mouseChildren = false;
			this.addChild(this.markerOutliner);
	
			/*
			 * This is our mainContainer what will happen
			 * is that Flar will give us a transformation
			 * matrix based on the marker and we can use
			 * that transformation matrix to rotate the
			 * mainContainer
			 */
			mainContainer = new FLARBaseNode();

			/*
			 * This is a Transformation matrix which Flar will
			 * fill and then we will use this to rotate mainContainer
			 */
			trans = new FLARTransMatResult();
			
			//Main loop where all the magic happens
			this.addEventListener(Event.ENTER_FRAME, mainEnter);
		}
		
		private function onCompleteHandler(loadEvent:Event):void{
	        addChild(loadEvent.currentTarget.content);
		}

		
		private function GetX(detector:FLARSingleMarkerDetector):Number{
			return new Number(((detector.getSquare().sqvertex[0].x + detector.getSquare().sqvertex[1].x
							+ detector.getSquare().sqvertex[2].x + detector.getSquare().sqvertex[3].x)/4));
		}
		
		private function GetY(detector:FLARSingleMarkerDetector):Number{
			return new Number(((detector.getSquare().sqvertex[0].y + detector.getSquare().sqvertex[1].y
							+ detector.getSquare().sqvertex[2].y + detector.getSquare().sqvertex[3].y)/4));
		}
		
		private function mainEnter(e:Event):void 
		{
			/*
			* Draw the current video screen to our capture
			* Flar will use this to figure out where our marker is
			*/
			capture.draw(vid);
			
			/*
			 * detector.detectMarkerLite(raster, 80) <-if marker found
			 * detector.getConfidence() <-how confident flar is in its find
			 */
			if (detector.detectMarkerLite(raster, 80) && detector.getConfidence() > 0.4)
			{
				//Get the transfomration matrix for the current marker position
				detector.getTransformMatrix(trans);
			
				var rectangle:Rectangle = new Rectangle();
				rectangle.height = RECTANGLE_HEIGHT;
				rectangle.width = RECTANGLE_WIDTH;
				rectangle.x = 100;
				rectangle.y = GetY(detector);

				var auxi:FLARDoublePoint2d = new FLARDoublePoint2d(rectangle.x,rectangle.y);
				this.markerOutliner.drawRectangle(auxi,RECTANGLE_WIDTH,RECTANGLE_HEIGHT);
				
				Player_Img.x = rectangle.x;
				Player_Img.y = rectangle.y + rectangle.height/2;
				addChild(Player_Img);
				Player_Img.load(Player_URL);
				
				ballX += velX;
				ballY += velY;
				if((ballX > this.vid.width - x_boundarie) || (ballX <= 0)) {
					velX = -velX;
				}
				if( (ballY > this.vid.height - y_boundarie) || (ballY <= 0) ) {
					velY = -velY;
				}
					

				this.markerOutliner.drawBall(ballX,ballY,BALL_RADIUS);
				
				Ball_Img.x = ballX;
				Ball_Img.y = ballY;	
				addChild(Ball_Img);
				Ball_Img.load(Ball_URL);
	
				
				var BallWrapper:Rectangle = new Rectangle();
				
				BallWrapper.x = ballX - BALL_RADIUS;
				BallWrapper.y = ballY - BALL_RADIUS;
				
				BallWrapper.width = BallWrapper.height = 2 * BALL_RADIUS;
				
				if(rectangle.intersects(BallWrapper)){
					velX = -velX;
					velY = velY;	
				}
				//Translates and rotates the mainContainer so it looks right
				mainContainer.setTransformMatrix(trans);

			}
		}
		
		
	}
	
}